//package com.pony.iphone.service.impl;
//
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.pony.iphone.dto.QuestionAnswerDto;
//import com.pony.iphone.dto.QuestionAnswerErrorDto;
//import com.pony.iphone.dto.QuestionPageDto;
//import com.pony.iphone.dto.QuestionStableDTO;
//import com.pony.iphone.entity.Library;
//import com.pony.iphone.entity.Question;
//import com.pony.iphone.mapper.LibraryMapper;
//import com.pony.iphone.mapper.QuestionMapper;
//import com.pony.iphone.mq.QuestionMessageProducer;
//import com.pony.iphone.service.QuestionService;
//import com.pony.iphone.utils.AppHttpCodeEnum;
//import com.pony.iphone.utils.PageParam;
//import com.pony.iphone.utils.R;
//import com.pony.iphone.vo.QuestionAnswerVO;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.function.Function;
//import java.util.stream.Collectors;
//
///**
// * @author pony
// */
//@Slf4j
//@Service
//public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService{
//
//    @Autowired
//    private QuestionMapper questionMapper;
//
//    @Autowired
//    private LibraryMapper libraryMapper;
//
//    // 注入消息生产者
//    @Autowired
//    private QuestionMessageProducer questionMessageProducer;
//
//    // 默认题库id 1
//    private static final Long DEFAULT_LIBRARY_ID = 1L;
//
//    /**
//     * 上传的一个问题以及其答案
//     * @param questionAnswerDto lua 上传的数据
//     * @return
//     */
//    @Override
//    @Transactional
//    public R uploadForLua(QuestionAnswerDto questionAnswerDto) {
//        // 1、获取问题
//        String questionStr = questionAnswerDto.getQuestion();
//        System.out.println("上传的问题是：" + questionStr);
//
//        List<String> answerList = questionAnswerDto.getAnswerList();
//        answerList.forEach(answer -> System.out.println("上传的答案是：" + answer));
//
//        // 2、查看数据库中是否有这个问题
//        // 2-1、根据dto的题库名称查询是否有这个题库
//        LambdaQueryWrapper<Library> libraryQw = new LambdaQueryWrapper<>();
//        libraryQw.eq(Library::getName, questionAnswerDto.getLibraryName());
//        Library library = libraryMapper.selectOne(libraryQw);
//        // 如果没有查到题库
//        if (library==null){
//            return R.error(AppHttpCodeEnum.ERROR)
//                    .message(questionAnswerDto.getLibraryName() + "，此题库不存在，请先创建此题库！");
//        }
//        // 2-2、如果查到了题库，则根据题库id和题目的名字，查询问题
//        Question question = questionMapper.selectQuestionByLibraryIdAndQuestionName(library.getId(), questionStr);
//
//        // 3、不存在的问题，则持久化到数据库
//        if (question==null){
//            boolean uploadResult = uploadQuestion(questionAnswerDto, library.getId());
//            if (uploadResult){
//                return R.success(AppHttpCodeEnum.SUCCESS, "单个问题上传成功！");
//            }
//            return R.error(AppHttpCodeEnum.ERROR, "单个问题上传失败！");
//        }
//        // 4、存在问题，不需要动
//        return R.success(AppHttpCodeEnum.SUCCESS, "单个问题上传成功！");
//    }
//
////    /**
////     * lua：获取一个问题的答案
////     * @param questionAnswerDto
////     * @return
////     */
////    @Override
////    @Transactional
////    public R getAnswerForLua(QuestionAnswerDto questionAnswerDto) {
////        // 1、获取问题和答案
////        String questionStr = questionAnswerDto.getQuestion();
////        List<String> answerList = questionAnswerDto.getAnswerList();
////
////        // 2、先查询数据库中是否有这个问题
////        LambdaQueryWrapper<Library> libraryQw = new LambdaQueryWrapper<>();
////        libraryQw.eq(Library::getName, questionAnswerDto.getLibraryName());
////        Library library = libraryMapper.selectOne(libraryQw);
////        // 2-1、如果没有查到题库
////        if (library==null){
////            return R.error(AppHttpCodeEnum.ERROR)
////                    .message(questionAnswerDto.getLibraryName() + "，此题库不存在，请先创建此题库！");
////        }
////        // 2-2、如果查到了题库，则根据题库id和题目的名字，查询问题
////        Question question = questionMapper.selectQuestionByLibraryIdAndQuestionName(library.getId(), questionStr);
////
////        if (question==null){
////            System.out.println("没有找到问题");
////        }else {
////            System.out.println(question.toString());
////        }
////
////        // 3、没有问题，则将新问题存到数据库并随机选择一个答案选择
////        if (question==null){
////            boolean uploadResult = uploadQuestion(questionAnswerDto, library.getId());
////            // 将新问题添加到数据库，成功，返回一个随机的答案
////            if (uploadResult){
////                return R.success(AppHttpCodeEnum.SUCCESS)
////                        .message("这是一个新问题，新问题上传成功，并返回一个随机的选项")
////                        .data("answer", questionAnswerDto.getRandomAnswer());
////            }
////            // 将新问题添加到数据库，失败，返回一个随机的答案
////            return R.error(AppHttpCodeEnum.ERROR)
////                    .message("单个问题上传失败！")
////                    .data("answer", questionAnswerDto.getRandomAnswer());
////        }else { // 4、有这个问题，根据选择权重较大的选项返回
////            return R.success(AppHttpCodeEnum.SUCCESS)
////                    .message("问题已经存在数据库，返回一个权重较大的选项")
////                    .data("answer", question.getWeightAnswer());
////        }
////    }
//
//    /**
//     * lua：获取一个问题的答案
//     */
//    @Override
//    @Transactional
//    public R getAnswerForLua(QuestionAnswerDto questionAnswerDto) {
//        // 1、获取问题和答案
//        String questionStr = questionAnswerDto.getQuestion();
//        List<String> answerList = questionAnswerDto.getAnswerList();
//
//        // 2、先查询数据库中是否有这个问题
//        LambdaQueryWrapper<Library> libraryQw = new LambdaQueryWrapper<>();
//        libraryQw.eq(Library::getName, questionAnswerDto.getLibraryName());
//        Library library = libraryMapper.selectOne(libraryQw);
//
//        // 2-1、如果没有查到题库
//        if (library == null) {
//            return R.error(AppHttpCodeEnum.ERROR)
//                    .message(questionAnswerDto.getLibraryName() + "，此题库不存在，请先创建此题库！");
//        }
//
//        // 2-2、如果查到了题库，则根据题库id和题目的名字，查询问题
//        Question question = questionMapper.selectQuestionByLibraryIdAndQuestionName(library.getId(), questionStr);
//
//        log.info("查询问题结果: {}", question != null ? question.toString() : "未找到问题");
//
//        // 3、没有问题，则将新问题存到数据库并随机选择一个答案选择
//        if (question == null) {
//            boolean uploadResult = uploadQuestion(questionAnswerDto, library.getId());
//
//            if (uploadResult) {
//                // 将新题目发送到消息队列（异步处理）
//                try {
//                    boolean sentToQueue = questionMessageProducer.sendQuestion(
//                            questionAnswerDto.getQuestion(),
//                            questionAnswerDto.getAnswerList(),
//                            questionAnswerDto.getLibraryName()
//                    );
//
//                    log.info("新题目处理结果 - 数据库: 成功, 消息队列: {}", sentToQueue);
//
//                } catch (Exception e) {
//                    log.error("发送新题目到消息队列失败，但不影响主流程", e);
//                }
//
//                return R.success(AppHttpCodeEnum.SUCCESS)
//                        .message("这是一个新问题，新问题上传成功，并返回一个随机的选项")
//                        .data("answer", questionAnswerDto.getRandomAnswer());
//            }
//
//            // 将新问题添加到数据库，失败，返回一个随机的答案
//            return R.error(AppHttpCodeEnum.ERROR)
//                    .message("单个问题上传失败！")
//                    .data("answer", questionAnswerDto.getRandomAnswer());
//
//        } else {
//            // 4、有这个问题，根据选择权重较大的选项返回
//            return R.success(AppHttpCodeEnum.SUCCESS)
//                    .message("问题已经存在数据库，返回一个权重较大的选项")
//                    .data("answer", question.getWeightAnswer());
//        }
//    }
//
//    /**
//     * lua：整个答题链路，失败的处理，将本次答题链路，所选的答案的分数加1，然后存到数据库中
//     * @param questionAnswerErrorDtoList 整个答题链路，包含所有问题和与之对应的所有答案选项
//     * @return R
//     */
//    @Override
//    @Transactional
//    public R uploadErrorLua(ArrayList<QuestionAnswerErrorDto> questionAnswerErrorDtoList) {
//        // 1、将dtoList所有的问题，组成一个集合
//        List<String> questions = questionAnswerErrorDtoList.stream()
//                .map(QuestionAnswerErrorDto::getQuestion)
//                .toList();
//
//        // 2、批量查询所有相关的问题以及答案
//        // 2-1、先查询有没有题库
//        String libraryName = questionAnswerErrorDtoList.get(0).getLibraryName();
//        LambdaQueryWrapper<Library> libraryQw = new LambdaQueryWrapper<>();
//        libraryQw.eq(Library::getName, libraryName);
//        Library library = libraryMapper.selectOne(libraryQw);
//        // 如果没有查到题库
//        if (library==null){
//            return R.error(AppHttpCodeEnum.ERROR)
//                    .message(libraryName + "，此题库不存在，请先创建此题库！");
//        }
//        // 2-2、如果查到了题库，则根据题库id 和 dto题目的问题名字list，查询范围内问题列表
//        List<Question> questionList = questionMapper.selectQuestionsByLibraryIdAndQuestionList(library.getId(),questions);
//        System.out.println("数据库查询到的问题列表：");
//        System.out.println(questionList);
//        // 3、构建问题映射，List -> Map，问题作为key，流本身作为value
//        Map<String, Question> questionMap = questionList.stream()
//                .collect(Collectors.toMap(Question::getQuestion, Function.identity()));
//
//        System.out.println("问题集合是：" + questionMap);
//
//        // 4、根据问题文本找到，questionMap中的问题对象，然后对应选项的分数+1，重新组合数据到list中
//        // 最终组装的questionList
//        List<Question> updateQuestionList = new ArrayList<>();
//
//        for (QuestionAnswerErrorDto errorDto : questionAnswerErrorDtoList) {
//            System.out.println("dto是：" + errorDto.toString());
//            // 获取 dto 问题
//            String questionStr = errorDto.getQuestion();
//            System.out.println("dto-问题是：" + errorDto.toString());
//            // 获取 dto 答案
//            String selectedAnswer = errorDto.getAnswer();
//            System.out.println("dto-答案是：" + selectedAnswer);
//
//            // 4-1、根据 dto 问题文本，从 map 中查询出question对象
//            Question question = questionMap.get(questionStr);
//            System.out.println("参数判断");
//            System.out.println(question);
//            System.out.println(question.getAnswer());
//            // 检查问题是否存在且 answer 不为 null
//            if (question != null && question.getAnswer() != null) {
//                HashMap<String, Long> answerMap = question.getAnswer();
//                // 检查答案选项是否存在
//                if (answerMap.containsKey(selectedAnswer)) {
//                    // 4-2、将选中答案的分数+1
//                    answerMap.put(selectedAnswer, answerMap.get(selectedAnswer) + 1);
//                    // 4-3、组装新数据到list中
//                    updateQuestionList.add(question);
//                }
//            }
//        }
//
//        System.out.println("更新后的问题：");
//        System.out.println(updateQuestionList);
//        updateQuestionList.forEach(question -> System.out.println("更新后的问题：" + question.toString()));
//        // 5、批量更新
//        if (CollectionUtils.isNotEmpty(questions)) {
//            updateBatchById(updateQuestionList);
//        }
//
//        return R.success(AppHttpCodeEnum.SUCCESS, "答题链路处理完成");
//    }
//
//    /**
//     * 上传单个问题以及所有答案 到数据库 中
//     * @param questionAnswerDto 前端传的问题
//     * @return 新插入问题的ID，如果插入失败则返回null
//     */
//    public boolean uploadQuestion(QuestionAnswerDto questionAnswerDto, Long libraryId){
//        // 答案选项
//        List<String> answerList = questionAnswerDto.getAnswerList();
//        HashMap<String, Long> answerMap = new HashMap<>();
//        // 1、组装数据
//        Question newQuestion = new Question();
//        newQuestion.setQuestion(questionAnswerDto.getQuestion());
//        // 新题的选项的分数都是0
//        answerList.forEach(answer -> answerMap.put(answer, 0L));
//        newQuestion.setAnswer(answerMap);
//        // 2、持久化到数据库
//        // 2-1、根据题库id 和 问题查询数据库，有没有这个问题
//        Question questionRes = questionMapper.selectQuestionByLibraryIdAndQuestionName(libraryId, questionAnswerDto.getQuestion());
//
//        // 表的变化行数，1表示添加成功成功
//        int insertLib;
//        // 如果没有找到问题，则添加
//        if (questionRes == null){
//            // 2-2、问题表添加这个问题
//            int insert = questionMapper.insert(newQuestion);
//            if (insert != 1) {
//                // 返回新插入问题的ID
//                return false;
//            }
//            // 2-3、题库库表添加这个问题
//            insertLib = libraryMapper.addQuestionForLibrary(libraryId, newQuestion.getId());
//        }else {
//            insertLib = 1;
//        }
//        return insertLib == 1;
//    }
//
//    /**
//     * lua：获取当前一个题库所有问题的稳定版本，供脚本使用
//     * 这里只负责查询，而不计算（lua脚本需要流畅执行，没必要在这里进行计算来，lua脚本也没必要每次都获取最新的稳定）
//     * 计算会有专门的定时任务进行更新数据（每天晚上0点更新）
//     *
//     * 思路：就是当一个问题的答案有80%的被点击的概率，则就是这个问题的稳定版本
//     * 当然不是每个问题不一定有稳定版本，因为有一些题可能就没有标准答案，答案选那个都无所谓的
//     * 这时候就会随机选一个答案
//     * @param libraryName 题库id
//     * @param versionId 稳定版本id，非必传，不传的话就是获取最新的稳定版本
//     * @return R
//     */
//    @Override
//    public R getStableForLua(String libraryName, Long versionId) {
//        try {
//            // 1、参数校验
//            if (libraryName == null || libraryName.trim().isEmpty()) {
//                return R.error(AppHttpCodeEnum.PARAMETER_LACK)
//                        .message("题库名称不能为空！");
//            }
//            // 2、检查题库是否存在
//            Long libraryId = questionMapper.findLibraryIdByName(libraryName);
//            if (libraryId == null) {
//                return R.error(AppHttpCodeEnum.ERROR)
//                        .message("题库 '" + libraryName + "' 不存在！");
//            }
//            // 3、查询结果
//            List<QuestionAnswerVO> result = getFinalAnswers(libraryName, versionId);
//
//            if (result.isEmpty()) {
//                log.warn("题库: '{}' , 版本Id: '{}' 下没有找到任何问题", libraryName, versionId);
//                return R.success(AppHttpCodeEnum.SUCCESS).data("data", result)
//                        .message("题库 '" + libraryName + "' 下没有找到任何问题");
//            }
//
//            log.info("成功查询题库: {} 版本ID: {} 的稳定答案，共 {} 个问题",
//                    libraryName, versionId, result.size());
//
//            return R.success(AppHttpCodeEnum.SUCCESS).data("data", result);
//
//        } catch (Exception e) {
//            log.error("查询题库稳定版本失败，题库名称: {} 版本ID: {}", libraryName, versionId, e);
//            return R.error(AppHttpCodeEnum.ERROR)
//                    .message("查询失败: " + e.getMessage());
//        }
//    }
//
//    /**
//     * 获取最终答案列表
//     * @param libraryName 题库名称
//     * @param versionId 版本名称
//     * @return 最终答案列表
//     */
//    private List<QuestionAnswerVO> getFinalAnswers(String libraryName, Long versionId) {
//        // 1. 先获取题库下的所有问题
//        List<Question> allQuestions = questionMapper.findQuestionsByLibrary(libraryName);
//        log.info("问题列表");
////        if (log.isDebugEnabled()) {
//            for (int i = 0; i < allQuestions.size(); i++) {
//                Question q = allQuestions.get(i);
//                log.info("问题 {}: ID={}, 内容='{}', 答案选项={}",
//                        i + 1, q.getId(), q.getQuestion(), q.getAnswer());
//            }
////        }
//
//        // 2. 获取稳定版本答案
//        Map<Long, QuestionStableDTO> stableAnswers = getStableAnswers(libraryName, versionId);
//
//        // 3. 构建最终结果
//        List<QuestionAnswerVO> result = new ArrayList<>();
//        for (Question question : allQuestions) {
//            QuestionAnswerVO vo = buildQuestionAnswerVO(question, stableAnswers);
//            result.add(vo);
//        }
//
//        return result;
//    }
//
//    /**
//     * 获取稳定版本答案
//     * @param libraryName 题库名称
//     * @param versionId 版本名称
//     * @return 稳定版本答案列表
//     */
//    private Map<Long, QuestionStableDTO> getStableAnswers(String libraryName, Long versionId) {
//        List<QuestionStableDTO> stableList;
//
//        if (versionId != null) {
//            // 查询指定版本
//            stableList = questionMapper.findStableAnswersByVersion(libraryName, versionId);
//        } else {
//            // 查询当前稳定版本
//            stableList = questionMapper.findCurrentStableAnswers(libraryName);
//        }
//
//        // 转换为Map，key为questionId
//        return stableList.stream()
//                .collect(Collectors.toMap(QuestionStableDTO::getQuestionId, Function.identity()));
//    }
//
//    /**
//     * 构建问题答案VO
//     */
//    private QuestionAnswerVO buildQuestionAnswerVO(Question question,
//                                                   Map<Long, QuestionStableDTO> stableAnswers) {
//        // 检查是否有稳定版本答案
//        QuestionStableDTO stableDTO = stableAnswers.get(question.getId());
//        if (stableDTO != null && stableDTO.getStableAnswer() != null) {
//            // 使用稳定版本答案
//            return new QuestionAnswerVO(
//                    question.getId(),
//                    question.getQuestion(),
//                    stableDTO.getStableAnswer(),
//                    stableDTO.getVersion()
//            );
//        } else {
//            // 随机选择答案
//            String randomAnswer = question.getRandomAnswer();
//            return new QuestionAnswerVO(
//                    question.getId(),
//                    question.getQuestion(),
//                    randomAnswer
//            );
//        }
//    }
//
//    /**
//     * 管理系统：获取问题管理系统分页信息
//     * @param pageParam 分页参数
//     * @param libraryId 题库id 非必传
//     * @return
//     */
//    @Override
//    public R getPage(PageParam pageParam, Long libraryId, String questionKey) {
//        // 创建分页对象
//        Page<QuestionPageDto> page = new Page<>(pageParam.getPageCurrent(), pageParam.getPageSize());
//
//        // 处理默认题库ID
//        Long actualLibraryId = (libraryId == null) ? DEFAULT_LIBRARY_ID : libraryId;
//        System.out.println("查询题库题目，题库ID: " + actualLibraryId);
//        // 执行分页查询
//        Page<QuestionPageDto> resultPage = questionMapper.selectQuestionsByLibraryId(page, actualLibraryId, questionKey);
//        // 转换每个 QuestionPageDto 中的 answerMap 为 answerList
//        resultPage.getRecords().forEach(QuestionPageDto::convertAnswerMapToList);
//        return R.success(AppHttpCodeEnum.SUCCESS)
//                .message("分页信息查询成功！")
//                .data("questionPage", resultPage);
//    }
//}
